<template>
  <div class="tag-table tag-tree-table">
    <el-table
      :data="tableData"
      v-loading="loading"
      header-cell-class-name="header-cell-class"
      :row-style="showRow"
      :cell-class-name="cellClass"
      :max-height="maxHeight"
      stripe
    >
      <el-table-column
        v-for="item in columnsShow"
        :label="item.label"
        :key="item.prop"
        :width="item.width"
        :min-width="item.minWidth"
        :align="item.align || 'left'"
        :header-align="item.headerAlign || 'center'"
        :class-name="item.expand ? 'expand-class' : ''"
        :show-overflow-tooltip="true"
      >
        <template slot-scope="scope">
          <template v-if="scope.row.searchRow">
            <div v-if="item.search">
              <el-input
                v-if="!item.dict"
                v-model="item.searchKey"
                @keyup.enter.native="searchFun(item)"
                @blur="searchFun(item)"
                ><i slot="suffix" class="el-input__icon el-icon-close" @click="clearSearch(item)"></i
              ></el-input>
              <el-select v-else v-model="item.searchKey" @change="searchFun(item)">
                <el-option label="-" value=""></el-option>
                <el-option
                  v-for="dict in $dictList(item.dict)"
                  :key="dict.key"
                  :label="dict.value"
                  :value="dict.key"
                ></el-option>
              </el-select>
            </div>
          </template>
          <slot v-else :scope="scope" :name="item.prop">
            <template v-if="item.expand">
              <span :style="{ 'padding-left': (scope.row.treeLevel - 1) * indent + 'px' }" />
              <span v-if="showSperadIcon(scope.row)" class="tree-ctrl" @click="toggleExpanded(scope.$index)">
                <i v-if="!scope.row._expand" class="el-icon-caret-right" />
                <i v-else class="el-icon-caret-bottom" />
              </span>
              <span v-else-if="scope.row[level] !== 1">
                <i class="tree-round"></i>
              </span>
              <span v-else :style="{ 'padding-left': '16px' }"></span>
              <span v-if="scope.row[item.icon]" class="tree-icon">
                <icon-svg :name="scope.row[item.icon]"></icon-svg>
              </span>
            </template>
            <span v-if="item.dict">{{ getDictValue(scope.row[item.prop], item.dict) }}</span>
            <span v-else>{{ scope.row[item.prop] }}</span>
          </slot>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: 'tag-tree-table',
  props: {
    data: {
      type: Array,
      required: true,
      default: () => []
    },
    loading: {
      type: Boolean,
      default: false
    },
    columns: {
      type: Array,
      default: () => []
    },
    indent: {
      type: Number,
      default: 20
    },
    children: {
      type: String,
      default: '_children'
    },
    level: {
      type: String,
      default: 'treeLevel'
    },
    maxHeight: {
      default: 'auto'
    }
  },
  data() {
    return {
      searchShow: false,
      searchList: []
    }
  },
  computed: {
    tableData() {
      var data = []
      if (this.searchShow) {
        data.push({
          searchRow: true
        })
      }
      var searchData = this.getSearchData()
      return data.concat(searchData)
    },
    columnsShow() {
      var arr = this.columns.filter(item => item.show)
      return arr
    }
  },
  methods: {
    showRow({ row }) {
      const parent = row._parent
      var show = parent ? parent._expand && parent._show : true
      row._show = show
      if (this.searchList.length !== 0) {
        show = true
      }
      return show ? '' : 'display:none;'
    },
    cellClass({ row }) {
      if (row.searchRow) {
        return 'cell-search-class'
      } else {
        return 'cell-class'
      }
    },
    showSperadIcon(record) {
      return this.searchList.length === 0 && record[this.children] && record[this.children].length > 0
    },
    toggleExpanded(trIndex) {
      const record = this.tableData[trIndex]
      const expand = !record._expand
      record._expand = expand
    },
    searchToggle() {
      this.searchShow = !this.searchShow
    },
    searchFun(item) {
      var list = this.searchList
      if (item.searchKey.length === 0) {
        for (var i = 0; i < list.length; i++) {
          if (list[i].prop === item.prop) {
            list.splice(i, 1)
            break
          }
        }
      } else {
        var newParams = true
        for (var u = 0; u < list.length; u++) {
          if (list[u].prop === item.prop) {
            list[u].key = item.searchKey
            newParams = false
            break
          }
        }
        if (newParams) {
          list.push({
            prop: item.prop,
            key: item.searchKey,
            dict: item.dict
          })
        }
      }
    },
    clearSearch(item) {
      item.searchKey = ''
      this.searchFun(item)
    },
    getSearchData() {
      var data = this.data
      var params = this.searchList
      for (var i = 0; i < params.length; i++) {
        data = data.filter(item => {
          if (params[i].dict) {
            return item[params[i].prop] == params[i].key
          } else {
            return item[params[i].prop].indexOf(params[i].key) !== -1
          }
        })
        if (data.length === 0) break
      }
      return data
    },
    spreadAll() {
      this.data.forEach(item => {
        item._expand = true
      })
    },
    foldAll() {
      this.data.forEach(item => {
        item._expand = false
      })
    },
    getDictValue(val, type) {
      if (typeof val === 'boolean') {
        val = val ? 1 : 0
      }
      return this.$dict(type)[val]
    }
  }
}
</script>

<style lang="scss">
.tag-tree-table {
  .tree-ctrl {
    cursor: pointer;
    font-size: 16px;
    i {
      color: $theme-color;
    }
  }
  .tree-icon {
    margin-right: 4px;
    vertical-align: middle;
  }
  .tree-round {
    display: inline-block;
    border-radius: 50%;
    border: 1px solid $theme-color;
    width: 8px;
    height: 8px;
    margin-right: 4px;
  }
  .icon-svg {
    font-size: 16px;
  }
}
</style>
